
/*
 *
 *
 * @name     attributes.numeric
 * @param    attributes.minValue     
 * @param    attributes.maxValue     
 * @param    attributes.decimal      Decimal separator (e.g. '.' or ',' - default is '.', 'no' if not authorized, ie int number)
 * @param    attributes.allowNegative      true ou false
 * @param    attributes.callbackErrorFormat     A function that runs if the number is not valid
 * @param    attributes.callbackErrorInterval     A function that runs if the number is not between min and max
 * @param    attributes.callbackNoError     A function that runs if the number is valid
 *
 */
jQuery.fn.numeric = function(attributes)
{
	noMoreBackspace();
	if (!attributes) 
    {attributes = {};}
	attributes.decimal = attributes.decimal || ".";
	if (this.val())
		{this.val(replaceStr(this.val(),",",attributes.decimal));}
	
	attributes.callbackErrorFormat = typeof attributes.callbackErrorFormat == "function" ? attributes.callbackErrorFormat : function(){};
	attributes.callbackErrorInterval = typeof attributes.callbackErrorInterval == "function" ? attributes.callbackErrorInterval : function(){};
	attributes.callbackNoError = typeof attributes.callbackNoError == "function" ? attributes.callbackNoError : function(){};
	 
	this.keypress(
		function(e)
		{
			var key = e.charCode ? e.charCode : e.keyCode ? e.keyCode : 0;
			// allow enter/return key (only when in an input box)
			if(key == 13 && this.nodeName.toLowerCase() == "input")
			{
				return true;
			}
			else if(key == 13)
			{
				return false;
			}
			var allow = false;
			// allow Ctrl+A
			if((e.ctrlKey && key == 97 /* firefox */) || (e.ctrlKey && key == 65) /* opera */) {return true;}
			// allow Ctrl+X (cut)
			if((e.ctrlKey && key == 120 /* firefox */) || (e.ctrlKey && key == 88) /* opera */) {return true;}
			// allow Ctrl+C (copy)
			if((e.ctrlKey && key == 99 /* firefox */) || (e.ctrlKey && key == 67) /* opera */) {return true;}
			// allow Ctrl+Z (undo)
			if((e.ctrlKey && key == 122 /* firefox */) || (e.ctrlKey && key == 90) /* opera */) {return true;}
			// allow or deny Ctrl+V (paste), Shift+Ins
			if((e.ctrlKey && key == 118 /* firefox */) || (e.ctrlKey && key == 86) /* opera */ || (e.shiftKey && key == 45)) {return false;}
			// if a number was not pressed
			if(key < 48 || key > 57)
			{
				/* '-' only allowed once */
				//alert(attributes.allowNegative + " " +  this.value.length + " " + key + " " + this.value);
				if(key == 45 && attributes.allowNegative && this.value.indexOf("-") == -1) {return true;}
				/* only one decimal separator allowed */
				if((key == attributes.decimal.charCodeAt(0) && this.value.indexOf(attributes.decimal) != -1) || attributes.decimal=='no')
          {allow = false;}
				// check for other keys that have special purposes
				if(key != 8 /* backspace */ && key != 9 /* tab */ && key != 13 /* enter */ && key != 35 /* end */ && key != 36 /* home */ && key != 37 /* left */ &&  key != 46 /* del */)
          {allow = false;}
				else
				{
					// for detecting special keys (listed above)
					// IE does not support 'charCode' and ignores them in keypress anyway
					if(typeof e.charCode != "undefined")
					{
						// special keys have 'keyCode' and 'which' the same (e.g. backspace)
						if(e.keyCode == e.which && e.which != 0)
						{
							allow = true;
						}
						// or keyCode != 0 and 'charCode'/'which' = 0
						else if(e.keyCode != 0 && e.charCode == 0 && e.which == 0)
						{
							allow = true;
						}
					}
				}
				// if key pressed is the decimal and it is not already in the field
				if(key == attributes.decimal.charCodeAt(0) && this.value.indexOf(attributes.decimal) == -1)
				{
					allow = true;
				}
			}
			else
			{
				allow = true;
			}			
			return allow;
		}
	);
	this.blur(
		function()
		{
			var val = jQuery(this).val();
			if(val != "")
			{
				var re = new RegExp("^\\d+$|\\d*" + attributes.decimal + "\\d+");
				var testCastOK = true;
				var resultCast;
				try{resultCast = Number($.trim(val));}
				catch(e)
				   {testCastOK = false;
					attributes.callbackErrorFormat.apply(this,[this]);}
				
				if(testCastOK && !isNaN(resultCast) && !re.exec(val))
					{attributes.callbackErrorFormat.apply(this,[this]);}
				else
					{attributes.callbackNoError(this,[this]);}
			}
		}
	);
	
	this.keyup(
		function()
		{
			var regExpStr = "[^0123456789.]";
			var filter = new RegExp(regExpStr, "g");
			var mnt;
			if (attributes.allowNegative && jQuery(this).val().length>0 && jQuery(this).val().indexOf("-")==0)
				{mnt = "-" + jQuery(this).val().substr(1).replace(filter,"");}
			else
				{mnt = jQuery(this).val().replace(filter,"");}
			
			if (mnt!=jQuery(this).val())
				{jQuery(this).val(mnt).trigger("change");}
			
			if (((attributes.minValue || attributes.minValue==0) && num<attributes.minValue) || ((attributes.maxValue || attributes.maxValue==0) && num>attributes.maxValue))
				{attributes.callbackErrorInterval.apply(this,[this]);}
			else
				{attributes.callbackNoError(this,[this]);}
		}
	);
	
	return this;
};
